﻿//==============================================================================
// Semaphore 
//------------------------------------------------------------------------------
///**
//  @file       Semaphore.h
//  @brief      Semaphore
//  @author     Riki
//*/
//==============================================================================

#pragma once

namespace LNote
{
namespace Core
{
namespace Threading
{

//==============================================================================
// ■ Semaphore
//------------------------------------------------------------------------------
///**
//  @brief      セマフォのクラス
//*/
//==============================================================================
class Semaphore
    : public Base::ReferenceObject
{
public:

	//----------------------------------------------------------------------
	///**
	//  @brief      コンストラクタ
	//  @param[in]  startCount	: 初期のカウント
	//  @param[in]  maxCount	: セマフォを取得できる最大数
	// */
	//----------------------------------------------------------------------
    Semaphore( int startCount, int maxCount );

	/// デストラクタ
    ~Semaphore();

public:

	//----------------------------------------------------------------------
	///**
	//  @brief      ロック
	//  @par
	//              カウントをひとつ減らします。
	//              この関数を呼んだ時にすでにカウントが 0 だった場合は待機します。
	//*/
	//----------------------------------------------------------------------
    void decrease();

	//----------------------------------------------------------------------
	///**
	//  @brief      アンロック
	//*/
	//----------------------------------------------------------------------
    void increase();

#if defined(LNOTE_WIN32)
	/// タイムアウト実装版 (true:取得できた)
    bool decrease( lnU32 ms );
#endif

private:

#if defined(LNOTE_WIN32)
	HANDLE	mHandle;
	int		mMaxCount;
#else
    int             mValue;
    int             mMaxCount;
    pthread_mutex_t mMutex;
    pthread_cond_t  mCondition;
    
#endif
};

} // namespace Threading
} // namespace Core
} // namespace LNote

//==============================================================================
//
//==============================================================================